package com.card.game.room;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.jboss.netty.channel.ChannelHandlerContext;
import org.quartz.JobDetail;

import com.card.common.CardContants;
import com.card.common.MessageComm;
import com.card.game.BasePlayer;
import com.card.game.BasePlayer.UserState;
import com.card.game.Card;
import com.card.game.DisbandReply;
import com.card.game.Player;
import com.card.game.PlayerEvent;
import com.card.game.event.EventType;
import com.card.game.room.record.GamePlayer;
import com.card.game.room.record.RoomRecord;
import com.card.game.utils.MjUtils;
import com.card.message.JsonMessageCenter;
import com.card.setting.GameSetting;
import com.card.timer.GameTimerManager;
import com.card.user.User;
import com.card.user.UserCurrency.CurrencyKind;
import com.card.user.UserUtils;
import com.google.common.collect.Lists;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.xiaoao.net.common.GameConstants;
import com.xiaoao.net.db.DBManager;
import com.xiaoao.net.db.Entity;
import com.xiaoao.net.global.Global;
import com.xiaoao.net.json.message.JsonMessage;
import com.xiaoao.net.utils.PrimaryKey;
import com.xiaoao.net.utils.StringUtil;

public abstract class AbstractRoom {
	// private transient static final AtomicInteger ROOMIDSEQUENCE = new
	// AtomicInteger(100);
	protected Vector<BasePlayer> playerList = new Vector<>();
	protected transient Vector<Card> tableCards;
	protected int id;
	protected int roomType;
	protected RoomSetting roomSetting;
	private transient JobDetail roomJobDetail;
	protected RoomState state = RoomState.Wait;
	protected transient RoomState lastState;
	protected transient long stateChangeTime;
	protected String ownerId;// 房主
	protected boolean isStartGame = false;
	public int playNum = 0;
	protected transient String firstDisandRequestId;
	protected transient long firstDisandTime;
	protected transient String breakId;
	public boolean isMatchRoom = false;

	public AbstractRoom(int roomType, String ownerId) {
		this.id = RoomManager.getInstance().randomRoomId();
		this.roomType = roomType;
		this.stateChangeTime = System.currentTimeMillis();
		this.ownerId = ownerId;
	}

	public int getId() {
		return id;
	}

	// 房间类型
	public int getRoomType() {
		return roomType;
	}

	// 添加玩家
	public void addPlayer(BasePlayer player) {
		int oldSize = this.playerList.size();
		this.playerList.add(player);
		int newSize = this.playerList.size();
		if (oldSize == newSize) {
			Global.logErrorMessage("!!!!!!!!!--加入失败!!---");
		}
		player.getUser().setRoom(this);
		checkSameIp(player);
		checkSameGPS(player);
		// 更新房间记录
		Entity entity = RoomManager.getInstance().getRoomRecordEntityByRoomId(id);
		if (entity != null) {
			Gson gson = new Gson();
			String jsonGamePlayerList = (entity.getProperty("gamePlayerList")).toString();
			List<GamePlayer> gamePlayerList = gson.fromJson(jsonGamePlayerList, new TypeToken<List<GamePlayer>>() {
			}.getType());
			for (GamePlayer gamePlayer : gamePlayerList) {
				if (gamePlayer == null || gamePlayer.getUserId() == null) {
					gamePlayer.setHeadPicUrl(player.img);
					gamePlayer.setNickName(player.nickName);
					gamePlayer.setUserId(player.getUserId());
					break;
				}
			}
			String jsonGamePlayerList2 = gson.toJson(gamePlayerList);
			entity.setProperty("gamePlayerList", jsonGamePlayerList2);
			DBManager.getInstance().saveOrUpdate(entity);
		}
	}

	public Vector<BasePlayer> getPlayerList() {
		return playerList;
	}

	// 房间设置
	public RoomSetting getRoomSetting() {
		return roomSetting;
	}

	// 修改房间设置
	public void setRoomSetting(RoomSetting roomSetting) {
		this.roomSetting = roomSetting;
	}

	// 发牌
	public void handOut(String userId, Card card, boolean isTing) {
	};

	// 技能
	public void doSkill(String userId, EventType type, int cardIndex) {
	};

	// 时间任务
	public void doTimedTask() {
		if (state == RoomState.DisbandRequest) {
			long waitTime = System.currentTimeMillis() - this.firstDisandTime;
			if (waitTime > GameSetting.HandOutTimeOutSecond * GameConstants.SECOND) {
				disbandRoom();
			}
		}
	}

	// 解散房间
	public void disbandRoom() {
	};

	public void disbandAgencyRoom() {
	};

	public void leaveRoom(String userId) {
		BasePlayer player = getPlayerById(userId);
		if (player != null) {
			playerList.remove(player);
			player.clear();
			sendRoomInfo();
		}
	}

	// 中断连接
	public void breakConnect(BasePlayer player) {
	};

	// 最大玩家个数
	public abstract int getMaxUserNum();

	// 启动游戏
	public void startGame() {
		if (isMatchRoom && this.roomType == CardContants.GAMETYPE_Ddz) {
			checkPlayerState();
		}
		broadPlayNum();
		if (this.isStartGame)
			return;
		this.isStartGame = true;
	}

	// 检查玩家状态
	public void checkPlayerState() {
		System.out.println("第一局");
		boolean haveNone = false;
		for (BasePlayer basePlayer : playerList) {
			if (basePlayer.getState() == UserState.None) {
				basePlayer.setState(UserState.Ready);
				haveNone = true;
			}
		}
		if (haveNone)
			sendRoomInfo();
	}

	// 房费
	public void spendRoom() {
		if (roomSetting.isAa()) {
			for (BasePlayer basePlayer : playerList) {
				User temp = basePlayer.getUser();
				temp.userCurrency().spend(CurrencyKind.Diamonds, -roomSetting.getPrice());
				temp.sendUserUpdateMessage();
			}
		} else {
			User ownUser = UserUtils.getUserByPrimaryKey(ownerId);
			int price = roomSetting.getPrice();
			ownUser.userCurrency().spend(CurrencyKind.Diamonds, price);
			ownUser.sendUserUpdateMessage();
			ownUser.createRoomSpendLog(this.roomType, -price);
		}
	}

	public boolean isOwner(String userId) {
		return false;
	}

	// 相同IP检测
	public void checkSameIp(BasePlayer player) {
	}
	
	//相同IP检测
	public void checkSameGPS(BasePlayer player) {
	}
	

	public void broadcast(JsonMessage message) {
		Iterator<BasePlayer> it = this.playerList.iterator();
		while (it.hasNext()) {
			BasePlayer player = it.next();
			JsonMessageCenter.getInstance().sendMessage(message, player);
		}
	}

	public void sendRoomInfo() {
		// 把房间里的信息发给自己
		JsonMessage message = new JsonMessage(MessageComm.S2C_RoomInfo);
		message.addProperty("room", this);
		broadcast(message);
	}

	public void sendRoomInfoToPlayer(BasePlayer player) {
		// 把房间里的信息发给自己
		JsonMessage message = new JsonMessage(MessageComm.S2C_RoomInfo);
		message.addProperty("room", this);
		JsonMessageCenter.getInstance().sendMessage(message, player);
	}

	public boolean isFull() {
		return false;
	}

	public boolean isHezhuangUser(String userId) {
		return false;
	}

	public void setEvent(PlayerEvent event) {
	}

	public List<String> getPlayerNameByIp(String ip) {
		List<String> names = Lists.newArrayList();
		Iterator<BasePlayer> it = this.playerList.iterator();
		while (it.hasNext()) {
			BasePlayer player = it.next();
			if (StringUtil.equals(ip, player.getIp())) {
				names.add(player.nickName);
			}
		}
		return names;
	}
	
	
	
	//检测相同的gps
	/*public List<String> getPlayerNameByGPS(BasePlayer player) {
		double gps = player.getGps();
		double gps2 = player.getGps2();
		List<String> names = Lists.newArrayList();
		Iterator<BasePlayer> it = this.playerList.iterator();
		while (it.hasNext()) {
			BasePlayer player1 = it.next();
			double distance = MjUtils.getDistance(gps, gps2, player1.getGps(), player1.getGps2());
			names.add("#"+player.nickName+"-"+player1.nickName+"-"+distance+"#");
		}
		return names;
	}*/
	

	public BasePlayer getPlayerById(String userId) {
		Iterator<BasePlayer> it = this.playerList.iterator();
		while (it.hasNext()) {
			BasePlayer player = it.next();
			if (StringUtil.equals(userId, player.getUserId())) {
				return player;
			}
		}
		return null;
	}

	public RoomState getState() {
		return state;
	}

	public void setState(RoomState state) {
		if (state == RoomState.DisbandRequest) {
			this.lastState = this.state;
		}
		this.state = state;
		this.stateChangeTime = System.currentTimeMillis();
	}

	public RoomState getLastState() {
		return lastState;
	}

	public BasePlayer getPlayerByTableIndex(int index) {
		Iterator<BasePlayer> it = this.playerList.iterator();
		while (it.hasNext()) {
			BasePlayer player = it.next();
			if (player.getTableIndex() == index) {
				return player;
			}
		}
		return null;
	}

	public void clearRoom() {
		if (this.roomJobDetail != null) {
			GameTimerManager.getInstance().deleteJob(roomJobDetail);
			this.roomJobDetail = null;
		}
		for (int i = playerList.size() - 1; i >= 0; i--) {
			BasePlayer player = playerList.get(i);
			player.clear();
		}
		playerList.clear();
		if (tableCards != null)
			tableCards.clear();
		RoomManager.getInstance().removeRoom(this);
		// 更新房间记录状态
		Entity entity = RoomManager.getInstance().getRoomRecordEntityByRoomId(id);
		if (entity != null) {
			entity.setProperty("gameStatus", 0);
			DBManager.getInstance().saveOrUpdate(entity);
		}
	}

	public boolean isStartGame() {
		return isStartGame;
	}

	public boolean allIsState(UserState state) {
		for (int i = playerList.size() - 1; i >= 0; i--) {
			BasePlayer player = playerList.get(i);
			if (player.getState() != state) {
				return false;
			}
		}
		return true;
	}

	public void allSetState(UserState state) {
		for (int i = playerList.size() - 1; i >= 0; i--) {
			BasePlayer player = playerList.get(i);
			player.setState(state);
		}
	}

	public void clearDisandReply() {
		this.firstDisandRequestId = null;
		this.firstDisandTime = 0;
		this.breakId = null;
		Iterator<BasePlayer> it = playerList.iterator();
		while (it.hasNext()) {
			BasePlayer p = it.next();
			p.getPlayerInfo().setDisbandReply(0);
		}
	}

	public void doLeaveAction(Player player) {
	}

	public void sendDisandRoomRequest() {
		if (this.state != RoomState.DisbandRequest) {
			setState(RoomState.DisbandRequest);
		}
		List<DisbandReply> replyList = Lists.newArrayList();
		Iterator<BasePlayer> it = playerList.iterator();
		while (it.hasNext()) {
			BasePlayer p = it.next();
			replyList.add(p.getPlayerInfo().getDisbandReply());
		}
		JsonMessage message = new JsonMessage(MessageComm.S2C_RoomDisbandRequest);
		message.addProperty("replyList", replyList);
		message.addProperty("firstId", firstDisandRequestId == null ? "-1" : firstDisandRequestId);
		message.addProperty("breakId", breakId == null ? "-1" : breakId);
		message.addProperty("lastSecond", getLastSecond(GameSetting.HandOutTimeOutSecond));
		broadcast(message);
	}

	public void checkDisandReply() {
		List<DisbandReply> replyList = Lists.newArrayList();
		Iterator<BasePlayer> it = playerList.iterator();
		int agreeNum = 0;
		int zaixianrenshu = 0;
		while (it.hasNext()) {
			BasePlayer p = it.next();
			DisbandReply temp = p.getPlayerInfo().getDisbandReply();
			if (p.isOnline()) {
				zaixianrenshu++;
			}
			replyList.add(temp);
			if (temp.getDisbandReply() == 1
			// || !p.isOnline()
			) {
				agreeNum++;
			}
		}
		JsonMessage message = new JsonMessage(MessageComm.S2C_RoomDisbandRequest);
		message.addProperty("replyList", replyList);
		message.addProperty("firstId", firstDisandRequestId == null ? "-1" : firstDisandRequestId);
		message.addProperty("breakId", breakId == null ? "-1" : breakId);
		message.addProperty("lastSecond", getLastSecond(GameSetting.HandOutTimeOutSecond));
		broadcast(message);

		if (getChangeStateTime() > 30 * GameConstants.SECOND) {
			agreeNum++;
			return;
		}
		if (zaixianrenshu - 1 == 0 || zaixianrenshu - 1 == -1) {
			disbandRoom();
			return;
		} else if (agreeNum >= zaixianrenshu - 1) {
			disbandRoom();
		}

		// if(agreeNum >= getMaxUserNum()-1) {
		// if(agreeNum >= zaixianrenshu-1) {
		// //所有人都同意了
		// disbandRoom();
		// }
	}

	public void setFirstDisandRequestId(String firstDisandRequestId) {
		if (this.firstDisandRequestId == null)
			this.firstDisandRequestId = firstDisandRequestId;
		if (this.firstDisandTime == 0)
			this.firstDisandTime = System.currentTimeMillis();
	}

	public void setBreakId(String breakId) {
		if (this.breakId == null)
			this.breakId = breakId;
		if (this.firstDisandRequestId == null)
			this.firstDisandRequestId = breakId;
		if (this.firstDisandTime == 0)
			this.firstDisandTime = System.currentTimeMillis();
	}

	public void startTime() {
		if (this.roomJobDetail == null) {
			this.roomJobDetail = GameTimerManager.getInstance().addRoomTimer(id);
		}
	}

	public void endGame() {
		if (tableCards != null)
			tableCards.clear();
		setState(RoomState.Wait);
		for (int i = playerList.size() - 1; i >= 0; i--) {
			BasePlayer basePlayer = playerList.get(i);
			basePlayer.endGame();
		}
		if (!isMatchRoom() && playNum == 1) {
			spendRoom();
		}
	}

	public void broadPlayNum() {
		JsonMessage message1 = JsonMessage.createMessage(MessageComm.S2C_TggGameOver);
		message1.addProperty("playNum", playNum);
		broadcast(message1);
	}

	public int getLastSecond(int allTime) {
		if (firstDisandTime > 0) {
			return (int) (allTime - (System.currentTimeMillis() - firstDisandTime) / GameConstants.SECOND);
		}
		return allTime;
	}

	public String getOwnerId() {
		return ownerId;
	}

	public Vector<Card> getTableCards() {
		return tableCards;
	}

	public int[] getPlayerScore() {
		int[] scores = new int[playerList.size()];
		for (BasePlayer p : playerList) {
			scores[p.getTableIndex()] = p.getScore();
		}
		return scores;
	}

	public boolean isMatchRoom() {
		return false;
	}

	public long getChangeStateTime() {
		return System.currentTimeMillis() - this.stateChangeTime;
	}

}
